package com.ccteam.fluidmusic.ui.nowplaying

import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.support.v4.media.session.PlaybackStateCompat
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.fragment.app.activityViewModels
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentPlaylistBottomSheetBinding
import com.ccteam.fluidmusic.databinding.PlaylistBottomSheetItemBinding
import com.ccteam.fluidmusic.view.adapters.ViewBindViewHolder
import com.ccteam.fluidmusic.view.adapters.viewbinding.ViewBindingAdapter
import com.ccteam.fluidmusic.view.base.LightBounceEdgeEffectFactory
import com.ccteam.fluidmusic.view.bean.LoadMessage
import com.ccteam.fluidmusic.view.bean.PlaylistMediaData
import com.ccteam.fluidmusic.widget.SNACKBAR_BOTTOM
import com.ccteam.fluidmusic.widget.snackbar
import com.ccteam.fluidmusic.ui.MainActivityViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.color.MaterialColors
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import kotlin.math.min

/**
 * @author Xiaoc
 * @since 2021/1/26
 **/
@AndroidEntryPoint
class PlaylistBottomSheetFragment: BottomSheetDialogFragment() {

    private var _binding: FragmentPlaylistBottomSheetBinding? = null
    private val binding get() = _binding!!

    private val mainActivityViewModel by activityViewModels<MainActivityViewModel>()


    @Inject lateinit var lightBounceEdgeEffectFactory: LightBounceEdgeEffectFactory

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentPlaylistBottomSheetBinding.inflate(inflater,container,false)
        return binding.root
    }

    /**
     * 在start方法中
     * 我们根据屏幕高度重新设置播放列表弹窗的高度
     */
    override fun onStart() {
        super.onStart()

        val layoutParams = binding.playlistBottomSheetContainer.layoutParams
        layoutParams.height = getPeekHeight()
        binding.playlistBottomSheetContainer.layoutParams = layoutParams
        (dialog as? BottomSheetDialog)?.behavior?.apply {
            skipCollapsed = true
            state = BottomSheetBehavior.STATE_EXPANDED
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        lightBounceEdgeEffectFactory.applyBounceView(binding.rvPlaylistBottomSheet,this)
        binding.rvPlaylistBottomSheet.edgeEffectFactory = lightBounceEdgeEffectFactory
        val adapter = PlaylistBottomSheetRVAdapter(playlistItemClickCallback)
        binding.rvPlaylistBottomSheet.adapter = adapter

        binding.rvPlaylistBottomSheet.scrollToPosition(
            mainActivityViewModel.currentItemInPlaylistIndex - min(2,adapter.itemCount)
        )

        binding.btnRepeatMode.setOnClickListener {
            when(mainActivityViewModel.repeatMode.value?.first){
                PlaybackStateCompat.REPEAT_MODE_ONE ->{
                    mainActivityViewModel.setRepeatMode(PlaybackStateCompat.REPEAT_MODE_NONE)
                    view.snackbar(R.string.description_repeat_off, SNACKBAR_BOTTOM).show()
                }
                PlaybackStateCompat.REPEAT_MODE_ALL,
                PlaybackStateCompat.REPEAT_MODE_GROUP ->{
                    mainActivityViewModel.setRepeatMode(PlaybackStateCompat.REPEAT_MODE_ONE)
                    view.snackbar(R.string.description_repeat_one, SNACKBAR_BOTTOM).show()
                }
                else ->{
                    mainActivityViewModel.setRepeatMode(PlaybackStateCompat.REPEAT_MODE_ALL)
                    view.snackbar(R.string.description_repeat_all, SNACKBAR_BOTTOM).show()
                }
            }
        }

        binding.btnShuffleMode.setOnClickListener {
            if(mainActivityViewModel.shuffleMode.value == false){
                mainActivityViewModel.setShuffleMode(PlaybackStateCompat.SHUFFLE_MODE_ALL)
                view.snackbar(R.string.description_shuffle_enabled, SNACKBAR_BOTTOM).show()
            } else {
                mainActivityViewModel.setShuffleMode(PlaybackStateCompat.SHUFFLE_MODE_NONE)
                view.snackbar(R.string.description_shuffle_disabled, SNACKBAR_BOTTOM).show()
            }
        }

        mainActivityViewModel.playlistMediaData.observe(viewLifecycleOwner, {
            // 如果播放列表为空，则显示空状态提示
            binding.statusView.isVisible = it.isNullOrEmpty()
            if(!it.isNullOrEmpty()){
                binding.tvCurrentPlaylist.text = getString(R.string.description_playing_count,it.size)
            } else {
                binding.statusView.changeToErrorStatus(LoadMessage.Empty)
                binding.tvCurrentPlaylist.text = getString(R.string.description_playing_count,0)
            }
        })

        mainActivityViewModel.repeatMode.observe(viewLifecycleOwner, {
            updateRepeatMode(it)
        })

        mainActivityViewModel.shuffleMode.observe(viewLifecycleOwner, {
            updateShuffleMode(it)
        })

        mainActivityViewModel.playlistMediaData.observe(viewLifecycleOwner, {
            it?.let {
                adapter.submitList(it)
            }
        })
    }

    private fun updateRepeatMode(repeatMode: Pair<Int,Int>){
        binding.btnRepeatMode.setIconResource(repeatMode.second)
    }

    private fun updateShuffleMode(shuffleMode: Boolean?){
        if(shuffleMode == true){
            binding.btnShuffleMode.backgroundTintList = ColorStateList.valueOf(requireContext().getColor(R.color.defaultSelectColor))
        } else {
            binding.btnShuffleMode.backgroundTintList = ColorStateList.valueOf(Color.TRANSPARENT)
        }
    }

    private val playlistItemClickCallback = object:
        PlaylistPlayerFragment.PlaylistItemClickCallback {

        override fun playlistItemClicked(view: View, playlistItem: PlaylistMediaData) {
            mainActivityViewModel.skipQueueItem(playlistItem.queueId)
        }

        override fun removeQueueItemClick(playlistItem: PlaylistMediaData) {
            mainActivityViewModel.removeQueueItem(playlistItem.queueId)
        }
    }

    class PlaylistBottomSheetRVAdapter(
        private val playlistItemCallback: PlaylistPlayerFragment.PlaylistItemClickCallback,
    ): ViewBindingAdapter<PlaylistBottomSheetItemBinding, PlaylistBottomSheetRVAdapter.PlaylistViewHolder, PlaylistMediaData>(PlaylistMediaData.diffCallback){


        inner class PlaylistViewHolder(
            binding: PlaylistBottomSheetItemBinding
        ): ViewBindViewHolder<PlaylistBottomSheetItemBinding>(binding){
            var item: PlaylistMediaData? = null

            init {
                binding.root.setOnClickListener {
                    item?.let { data ->
                        playlistItemCallback.playlistItemClicked(binding.root,data)
                    }
                }
                binding.btnDeleteQueueItem.setOnClickListener {
                    item?.let { data ->
                        playlistItemCallback.removeQueueItemClick(data)
                    }
                }
            }
        }

        override fun createViewBinding(parent: ViewGroup, viewType: Int): PlaylistViewHolder {
            return PlaylistViewHolder(PlaylistBottomSheetItemBinding.inflate(LayoutInflater.from(parent.context),parent,false))
        }

        override fun bindItem(
            holder: PlaylistViewHolder,
            position: Int,
            item: PlaylistMediaData,
            payloads: MutableList<Any>
        ) {
            holder.item = item
            if(item.isPlaying){
                val colorPrimary = MaterialColors.getColor(holder.itemView,R.attr.colorPrimary)
                holder.binding.ivMusicWave.playAnimation()
                holder.binding.ivMusicWave.visibility = View.VISIBLE
                holder.binding.tvMusicArtist.setTextColor(colorPrimary)
                holder.binding.tvMusicTitle.setTextColor(colorPrimary)
            } else {
                val colorOnSurface = MaterialColors.getColor(holder.itemView,R.attr.colorOnSurface)
                holder.binding.ivMusicWave.cancelAnimation()
                holder.binding.ivMusicWave.visibility = View.GONE
                holder.binding.tvMusicTitle.setTextColor(colorOnSurface)
                holder.binding.tvMusicArtist.setTextColor(colorOnSurface)
            }

            holder.binding.tvMusicTitle.text = item.title
            holder.binding.tvMusicArtist.text = item.artist
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    /**
     * 根据屏幕高度，返回屏幕高度的3/4的值
     */
    private fun getPeekHeight(): Int{
        val height = resources.displayMetrics.heightPixels
        return height - height / 4
    }
}